home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <GL/glx.h>
- #include <GL/glu.h>
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <X11/keysym.h>
- #include <malloc.h>
- #include <assert.h>
-
- static int RGB_SB_attributes[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- None,
- };
-
- static int RGB_DB_attributes[] = {
- GLX_RGBA,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- static int CI_SB_attributes[] = {
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- static int CI_DB_attributes[] = {
- GLX_DOUBLEBUFFER,
- GLX_DEPTH_SIZE, 1,
- GLX_STENCIL_SIZE, 1,
- None,
- };
-
- int rgb = 1;
- int W = 500;
- int H = 500;
-
- /*
- ** A contour.
- */
- struct vert {
- GLdouble v[3];
- struct vert *next;
- };
-
- /*
- ** A polygon (multiple contours).
- */
- struct polygon {
- struct vert *contour;
- struct polygon *next;
- };
-
- #define SELECT_LINE 1
- #define SELECT_VERTEX 2
-
- struct polygon *thePoly = NULL;
- struct vert *foundVertex = NULL;
- int leftDown, middleDown, rightDown;
- int tessIt;
- int showTess;
- int doEdgeFlags;
- int gotError;
- int doubleBuf = 1;
- GLUtriangulatorObj *tobj;
- Display *dpy;
- Window window;
- Colormap cmap;
-
- unsigned char font6x10[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x38, 0x38, 0x10, 0x00,
- 0x00, 0x00, 0x54, 0x28, 0x54, 0x28, 0x54, 0x28, 0x54, 0x00,
- 0x08, 0x08, 0x08, 0x3c, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00,
- 0x10, 0x10, 0x18, 0x10, 0x5c, 0x40, 0x60, 0x40, 0x70, 0x00,
- 0x24, 0x24, 0x38, 0x24, 0x38, 0x38, 0x40, 0x40, 0x38, 0x00,
- 0x20, 0x20, 0x38, 0x20, 0x3c, 0x78, 0x40, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x28, 0x38, 0x00,
- 0x00, 0x00, 0x7c, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00,
- 0x3c, 0x20, 0x20, 0x20, 0x48, 0x58, 0x68, 0x68, 0x48, 0x00,
- 0x08, 0x08, 0x08, 0x08, 0x3c, 0x20, 0x30, 0x48, 0x48, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10, 0x10, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x00, 0x7c, 0x04, 0x08, 0x20, 0x40, 0x20, 0x08, 0x04, 0x00,
- 0x00, 0x7c, 0x40, 0x20, 0x08, 0x04, 0x08, 0x20, 0x40, 0x00,
- 0x00, 0x00, 0x28, 0x28, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x20, 0x7c, 0x10, 0x7c, 0x08, 0x04, 0x00,
- 0x00, 0x20, 0x6c, 0x38, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x00,
- 0x00, 0x00, 0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00,
- 0x00, 0x00, 0x10, 0x38, 0x14, 0x38, 0x50, 0x38, 0x10, 0x00,
- 0x00, 0x00, 0x48, 0x54, 0x28, 0x10, 0x28, 0x54, 0x24, 0x00,
- 0x00, 0x00, 0x34, 0x48, 0x54, 0x20, 0x50, 0x50, 0x20, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x18, 0x00,
- 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00,
- 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x28, 0x7c, 0x28, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00,
- 0x00, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x04, 0x00,
- 0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00,
- 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x50, 0x30, 0x10, 0x00,
- 0x00, 0x00, 0x7c, 0x40, 0x20, 0x18, 0x04, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x08, 0x04, 0x7c, 0x00,
- 0x00, 0x00, 0x08, 0x08, 0x7c, 0x48, 0x28, 0x18, 0x08, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x04, 0x64, 0x58, 0x40, 0x7c, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x64, 0x58, 0x40, 0x20, 0x18, 0x00,
- 0x00, 0x00, 0x20, 0x20, 0x10, 0x08, 0x08, 0x04, 0x7c, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x30, 0x08, 0x04, 0x34, 0x4c, 0x44, 0x38, 0x00,
- 0x00, 0x10, 0x38, 0x10, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00,
- 0x00, 0x20, 0x10, 0x18, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00,
- 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x08, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x38, 0x40, 0x58, 0x54, 0x4c, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x28, 0x10, 0x00,
- 0x00, 0x00, 0x78, 0x24, 0x24, 0x38, 0x24, 0x24, 0x78, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x78, 0x24, 0x24, 0x24, 0x24, 0x24, 0x78, 0x00,
- 0x00, 0x00, 0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00,
- 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x4c, 0x40, 0x40, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00,
- 0x00, 0x00, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00,
- 0x00, 0x00, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x44, 0x54, 0x6c, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x44, 0x44, 0x78, 0x00,
- 0x00, 0x04, 0x38, 0x54, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x44, 0x48, 0x50, 0x78, 0x44, 0x44, 0x78, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x40, 0x44, 0x38, 0x00,
- 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x10, 0x28, 0x28, 0x28, 0x44, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x44, 0x6c, 0x54, 0x54, 0x44, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44, 0x00,
- 0x00, 0x00, 0x7c, 0x40, 0x20, 0x10, 0x08, 0x04, 0x7c, 0x00,
- 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00,
- 0x00, 0x00, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00,
- 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x30, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x3c, 0x04, 0x38, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x58, 0x64, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x04, 0x04, 0x00,
- 0x00, 0x00, 0x38, 0x40, 0x7c, 0x44, 0x38, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x20, 0x20, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00,
- 0x38, 0x44, 0x38, 0x40, 0x30, 0x48, 0x34, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x30, 0x00, 0x10, 0x00,
- 0x30, 0x48, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x08, 0x00,
- 0x00, 0x00, 0x44, 0x48, 0x70, 0x48, 0x44, 0x40, 0x40, 0x00,
- 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00,
- 0x00, 0x00, 0x44, 0x54, 0x54, 0x54, 0x68, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00,
- 0x40, 0x40, 0x40, 0x58, 0x64, 0x64, 0x58, 0x00, 0x00, 0x00,
- 0x04, 0x04, 0x04, 0x34, 0x4c, 0x4c, 0x34, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0x40, 0x40, 0x64, 0x58, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0x04, 0x38, 0x40, 0x38, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x00,
- 0x00, 0x00, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x28, 0x54, 0x54, 0x44, 0x44, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00,
- 0x38, 0x44, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0c, 0x10, 0x08, 0x30, 0x08, 0x10, 0x0c, 0x00,
- 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
- 0x00, 0x00, 0x60, 0x10, 0x20, 0x18, 0x20, 0x10, 0x60, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x54, 0x24, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
-
- int fontbase;
-
- void initializeFont(void)
- {
- int i;
-
- fontbase=glGenLists(256);
- glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- for (i=0; i<128; i++) {
- glNewList(i+fontbase, GL_COMPILE);
- glBitmap(6, 10, 0.0, 0.0, 6.0, 0.0, font6x10+10*i);
- glEndList();
- }
- }
-
- void writeFont(char *string)
- {
- glListBase(fontbase);
- glCallLists(strlen(string), GL_BYTE, (unsigned char *) string);
- }
-
- void myBegin(GLenum which)
- {
- glBegin(which);
- }
-
- void myEnd(void)
- {
- glEnd();
- }
-
- void tessPoly(void)
- {
- struct polygon *poly;
- struct vert *vert;
-
- gluBeginPolygon(tobj);
- for (poly=thePoly; poly; poly=poly->next) {
- gluNextContour(tobj, GLU_UNKNOWN);
- for (vert=poly->contour; vert; vert=vert->next) {
- gluTessVertex(tobj, vert->v, vert->v);
- }
- }
- gluEndPolygon(tobj);
- }
-
- static void Redraw(GLenum mode)
- {
- struct polygon *poly;
- struct vert *vert;
-
- glClear(GL_COLOR_BUFFER_BIT);
- glPointSize(3);
-
- gotError = 0;
- glInitNames();
- if (tessIt) {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glColor3f(0.5, 0.5, 0.5);
- glIndexf(15);
- tessPoly();
- }
- if (!gotError && showTess) {
- glColor3f(1.0, 1.0, 0.0);
- glIndexf(3);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- tessPoly();
- }
- if (!gotError && doEdgeFlags) {
- glLineWidth(3);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glColor3f(0.0, 0.0, 1.0);
- glIndexf(4);
- gluTessCallback(tobj, GLU_EDGE_FLAG, (void *) glEdgeFlag);
- tessPoly();
- gluTessCallback(tobj, GLU_EDGE_FLAG, NULL);
- glLineWidth(1);
- }
-
- if (gotError) {
- glColor3f(1.0, 1.0, 1.0);
- glIndexf(7);
- glRasterPos2f(5.0, 15.0);
- glColor3f(0.0, 0.0, 1.0);
- glIndexf(4);
- writeFont((char *) gluErrorString(gotError));
- }
-
- /* So glLoadName will be legal -- strange semantics */
- glPushName(1);
- for (poly=thePoly; poly; poly=poly->next) {
- glColor3f(0.0, 1.0, 0.0);
- glIndexf(2);
- glLoadName(SELECT_LINE);
- for (vert=poly->contour; vert; vert=vert->next) {
- glPushName((GLuint) vert);
- glBegin(GL_LINES);
- glVertex2dv(vert->v);
- if (vert->next) {
- glVertex2dv(vert->next->v);
- } else {
- glVertex2dv(poly->contour->v);
- }
- glEnd();
- glPopName();
- }
- glColor3f(1.0, 0.0, 0.0);
- glIndexf(1);
- glLoadName(SELECT_VERTEX);
- for (vert=poly->contour; vert; vert=vert->next) {
- glPushName((GLuint) vert);
- glBegin(GL_POINTS);
- glVertex2dv(vert->v);
- glEnd();
- glPopName();
- }
- }
-
- if (mode == GL_RENDER) {
- glXSwapBuffers(dpy, window);
- }
- }
-
- static void Usage(void)
- {
- fprintf(stderr, "Usage: tesstest [-c] [-s]\n");
- fprintf(stderr, " -c: run in color index mode\n");
- fprintf(stderr, " -s: run in singlebuffer mode\n");
- exit(1);
- }
-
- static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
- {
- if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
- return GL_TRUE;
- }
- return GL_FALSE;
- }
-
- /*
- ** Create a new contour at x,y.
- */
- void newContour(int x, int y)
- {
- struct polygon *newPoly;
- struct vert *newCont;
- struct polygon **polyTail;
-
- newPoly = (struct polygon *) malloc(sizeof(struct polygon));
- newCont = (struct vert *) malloc(sizeof(struct vert));
-
- polyTail = &thePoly;
- while (*polyTail) {
- polyTail = &((*polyTail)->next);
- }
-
- *polyTail = newPoly;
- newPoly->next = NULL;
- newPoly->contour = newCont;
-
- newCont->next = NULL;
- newCont->v[0] = x;
- newCont->v[1] = y;
- newCont->v[2] = 0;
- }
-
- /*
- ** Create a new edge at this vertex
- */
- struct vert *addVertex(struct vert *where, int x, int y)
- {
- struct vert *newVert;
-
- newVert = (struct vert *) malloc(sizeof(struct vert));
-
- newVert->next = where->next;
- where->next = newVert;
- newVert->v[0] = x;
- newVert->v[1] = y;
- newVert->v[2] = 0;
-
- return newVert;
- }
-
- void deleteVertex(void)
- {
- struct polygon *poly, *poly2;
- struct vert *vert;
-
- if (!foundVertex) return;
-
- for (poly=thePoly; poly; poly=poly->next) {
- if (poly->contour == foundVertex) {
- poly->contour = foundVertex->next;
- free(foundVertex);
- foundVertex = NULL;
- if (poly->contour == NULL) {
- if (poly == thePoly) {
- thePoly = poly->next;
- free(poly);
- return;
- }
- for (poly2=thePoly; poly2; poly2=poly2->next) {
- if (poly2->next == poly) {
- poly2->next = poly->next;
- free(poly);
- return;
- }
- }
- }
- return;
- }
- for (vert=poly->contour; vert; vert=vert->next) {
- if (vert->next == foundVertex) {
- vert->next = foundVertex->next;
- free(foundVertex);
- foundVertex = NULL;
- return;
- }
- }
- }
- }
-
- void findVertex(int x, int y, int type)
- {
- static GLuint selectBuf[1000];
- GLint hits;
- GLint viewport[4];
- int i;
-
- foundVertex = NULL;
- glSelectBuffer(1000, selectBuf);
- (void) glRenderMode(GL_SELECT);
- glInitNames();
-
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
- glGetIntegerv(GL_VIEWPORT, viewport);
- gluPickMatrix(x, y, 6, 6, viewport);
- gluOrtho2D(0,W,0,H);
- glMatrixMode(GL_MODELVIEW);
-
- Redraw(GL_SELECT);
-
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
-
- hits = glRenderMode(GL_RENDER);
- if (hits <= 0) return;
-
- /*
- ** Each entry looks like:
- ** count (2)
- ** min z, max z
- ** SELECT_LINE or SELECT_VERTEX
- ** pointer to vertex.
- */
-
- i = 0;
- while (hits) {
- hits --;
- if (selectBuf[i] == 0) {
- i+= 3;
- continue;
- }
- assert(selectBuf[i] == 2);
- i += 3;
- if (selectBuf[i] == type) {
- foundVertex = (struct vert *) selectBuf[i+1];
- return;
- }
- i += 2;
- }
- }
-
- void moveVertex(int x, int y)
- {
- if (foundVertex) {
- foundVertex->v[0] = x;
- foundVertex->v[1] = y;
- }
- }
-
- void errorHandler(GLenum error)
- {
- if (gotError) {
- printf("Double errors!?!\n");
- }
- gotError = error;
- }
-
- static void Init(void)
- {
- glViewport(0,0,W,H);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0,W,0,H);
- glMatrixMode(GL_MODELVIEW);
-
- if (rgb) {
- glClearColor(0,0,0,0);
- } else {
- glClearIndex(0);
- }
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- tobj = gluNewTess();
- gluTessCallback(tobj, GLU_VERTEX, glVertex2dv);
- gluTessCallback(tobj, GLU_BEGIN, myBegin);
- gluTessCallback(tobj, GLU_END, myEnd);
- gluTessCallback(tobj, GLU_ERROR, errorHandler);
-
- initializeFont();
- }
-
- static void setColorMap(void)
- {
- XColor *xc;
- long i;
-
- xc = (XColor *) malloc(16 * sizeof(XColor));
- for (i=0; i<16; i++) {
- xc[i].pixel = i;
- xc[i].red = (i & 1) ? 65535 : 0;
- xc[i].green = (i & 2) ? 65535 : 0;
- xc[i].blue = (i & 4) ? 65535 : 0;
- if (i > 8) {
- xc[i].red /= 2;
- xc[i].green /= 2;
- xc[i].blue /= 2;
- }
- xc[i].flags = DoRed | DoGreen | DoBlue;
- }
- XStoreColors(dpy, cmap, xc, 16);
-
- free((void *) xc);
- }
-
- int main(int argc, char** argv)
- {
- XVisualInfo *vi;
- XSetWindowAttributes swa;
- GLXContext cx;
- XEvent event;
- GLboolean needDisplay;
- XColor white;
- int i;
-
- rgb = 1;
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- case 'c':
- rgb = GL_FALSE;
- break;
- case 's':
- doubleBuf = 0;
- break;
- default:
- Usage();
- }
- } else {
- Usage();
- }
- }
-
- dpy = XOpenDisplay(0);
- if (!dpy) {
- fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
- return -1;
- }
-
- vi = glXChooseVisual(dpy, DefaultScreen(dpy),
- doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
- (rgb ? RGB_SB_attributes : CI_SB_attributes));
- if (!vi) {
- fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
- getenv("DISPLAY"));
- return -1;
- }
-
- cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
- rgb ? AllocNone : AllocAll);
- white.red = ~0;
- white.green = ~0;
- white.blue = ~0;
- XAllocColor(dpy, cmap, &white);
-
- swa.border_pixel = 0;
- swa.background_pixel = white.pixel;
- swa.colormap = cmap;
- swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
- | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask;
- window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
- W, H,
- 0, vi->depth, InputOutput, vi->visual,
- CWBackPixel|CWBorderPixel|CWColormap|CWEventMask,
- &swa);
- XSetWMColormapWindows(dpy, window, &window, 1);
- XMapWindow(dpy, window);
- XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
-
- cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
- if (!glXMakeCurrent(dpy, window, cx)) {
- fprintf(stderr, "Can't make window current to context\n");
- return -1;
- }
-
- if (!rgb) {
- setColorMap();
- }
-
- Init();
-
- printf("\n\nc to create a new contour.\n");
- printf("d to delete a vertex.\n");
- printf("t to tessellate and draw the polygon.\n");
- printf("s to show the tessellation.\n");
- printf("e to draw the polygon in Polymode(GL_LINE) with edge flags.\n");
- printf("Left mouse moves a vertex.\n");
- printf("Middle mouse inserts a vertex into a contour.\n");
-
- needDisplay = GL_TRUE;
- leftDown = middleDown = rightDown = GL_FALSE;
- newContour(100, 100);
- findVertex(100, 100, SELECT_VERTEX);
- addVertex(foundVertex, 100, 400);
- findVertex(100, 400, SELECT_VERTEX);
- addVertex(foundVertex, 400, 400);
- findVertex(400, 400, SELECT_VERTEX);
- addVertex(foundVertex, 400, 100);
- foundVertex = NULL;
- for (;;) {
- do {
- GLboolean setNeed;
-
- XNextEvent(dpy, &event);
- setNeed = GL_TRUE;
- switch (event.type) {
- case Expose:
- break;
- case ConfigureNotify:
- W = event.xconfigure.width;
- H = event.xconfigure.height;
- glViewport(0,0,W,H);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0,W,0,H);
- glMatrixMode(GL_MODELVIEW);
- break;
- case ButtonPress:
- /*
- ** Only effectively allow one mouse button down at a time.
- */
- setNeed = GL_FALSE;
- leftDown = middleDown = rightDown = GL_FALSE;
- switch(event.xbutton.button) {
- case 1: /* Left - move vertex */
- findVertex(event.xbutton.x, H - event.xbutton.y,
- SELECT_VERTEX);
- moveVertex(event.xbutton.x, H - event.xbutton.y);
- leftDown = GL_TRUE;
- break;
- case 2: /* Middle - insert vertex */
- middleDown = GL_TRUE;
- findVertex(event.xbutton.x, H - event.xbutton.y,
- SELECT_LINE);
- if (foundVertex) {
- foundVertex = addVertex(foundVertex,
- event.xbutton.x, H - event.xbutton.y);
- }
- break;
- case 3: /* Right */
- rightDown = GL_TRUE;
- break;
- }
- break;
- case ButtonRelease:
- setNeed = GL_FALSE;
- switch(event.xbutton.button) {
- case 1:
- if (leftDown && foundVertex) {
- moveVertex(event.xbutton.x, H - event.xbutton.y);
- leftDown = GL_FALSE;
- setNeed = GL_TRUE;
- }
- break;
- case 2:
- if (middleDown && foundVertex) {
- moveVertex(event.xbutton.x, H - event.xbutton.y);
- middleDown = GL_FALSE;
- setNeed = GL_TRUE;
- }
- break;
- case 3:
- rightDown = GL_FALSE;
- break;
- }
- break;
- case MotionNotify:
- if (leftDown && foundVertex) {
- moveVertex(event.xmotion.x, H - event.xmotion.y);
- } else if (middleDown && foundVertex) {
- moveVertex(event.xmotion.x, H - event.xmotion.y);
- } else {
- setNeed = GL_FALSE;
- }
- break;
- case KeyPress:
- {
- char buf[100];
- int rv;
- KeySym ks;
-
- rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
- switch (ks) {
- case XK_C: case XK_c:
- newContour(event.xkey.x, H - event.xkey.y);
- break;
- case XK_D: case XK_d:
- findVertex(event.xbutton.x, H - event.xbutton.y,
- SELECT_VERTEX);
- if (foundVertex) {
- deleteVertex();
- } else setNeed = GL_FALSE;
- break;
- case XK_T: case XK_t:
- tessIt = 1-tessIt;
- break;
- case XK_S: case XK_s:
- showTess = 1-showTess;
- break;
- case XK_E: case XK_e:
- doEdgeFlags = 1-doEdgeFlags;
- break;
- case XK_Escape:
- return 0;
- default:
- setNeed = GL_FALSE;
- break;
- }
- }
- break;
- default:
- setNeed = GL_FALSE;
- break;
- }
- if (setNeed) needDisplay = GL_TRUE;
- } while (XPending(dpy) != 0);
-
- if (needDisplay) {
- needDisplay = GL_FALSE;
- Redraw(GL_RENDER);
- }
- }
- }
-
-
-